import Fluent
import FluentMySQLDriver
import Foundation
import NIOCore
import NIOSSL
import QueuesRedisDriver
import Redis
import SwiftyBeaver
import Vapor

  // 导入阿里云SDK依赖
import AlibabacloudDysmsapi20170525
import AlibabacloudDm20151123

public func configure(_ app: Application) async throws {
    //  app.logger.logLevel = .info // Vapor 日志系统
    // MARK: - 配置服务器
  app.http.server.configuration.port = 8080
  app.http.server.configuration.hostname = "0.0.0.0"
  app.http.server.configuration.supportVersions = [.one]
  app.http.server.configuration.responseCompression = .enabled
  app.http.server.configuration.requestDecompression = .enabled
  app.routes.defaultMaxBodySize = "100mb"
    // MARK: - 配置自定义日志
  LogManager.shared.configure()
  
    // MARK: - 配置云服务
    // 配置腾讯云短信服务
  app.tencentSMS = TencentSMSService(
    microserviceBaseURL: "http://localhost:5001",
    httpClient: app.client
  )
  
    // 配置腾讯云邮件服务
  app.tencentEmail = TencentEmailService(
    secretId: "AKIDU0NaciWEpJfrshYGrJJAqNkx79079yZx",
    secretKey: "Pkta9oIDNakkaSBj6PYVJvJVXO9gz60i",
    endpoint: "ses.tencentcloudapi.com",
    regionId: "ap-guangzhou",
    fromEmailAddress: "verify@noreply.bayanarabic.cn",
    domain: "noreply.bayanarabic.cn",
    registerTemplateId: 31657,
    loginTemplateId: 31658,
    resetPasswordTemplateId: 31659,
    bindEmailTemplateId: 31660
  )
  
    // 配置COS服务代理（使用微服务API）
  app.cosServiceProxy = COSServiceProxy(
    baseURL: "http://localhost:5000", // 使用localhost可以在本地环境中访问微服务
    httpClient: app.client
  )
  
  app.logger.info("腾讯云服务和微服务API代理初始化完成")
  
    // MARK: - 配置 TLS 证书
  var tls = TLSConfiguration.clientDefault
  tls.certificateVerification = .fullVerification
  tls.trustRoots =
    .default /*.file(homeDirectory.appendingPathComponent("Certs/isrgrootx1.pem").path)*/
    // MARK: - 配置MySQL数据库
  app.databases.use(
    DatabaseConfigurationFactory.mysql(
      hostname: "bayanarabic.cn",
      port: 3306,
      username: "KEN",
      password: "000",
      database: "testing_db",
      tlsConfiguration: tls,
      maxConnectionsPerEventLoop: 20,
      connectionPoolTimeout: .seconds(30)
    ), as: .mysql)
    // MARK: - 配置Redis数据库
    // 1. Redis 配置
  app.redis.configuration = try .init(
    hostname: "127.0.0.1",
    port: 6379,
    password: "Zhao@19930612",
    pool: .init(
      maximumConnectionCount: .maximumActiveConnections(20),  // 最大活动连接数
      minimumConnectionCount: 5,  // 最小连接数
      connectionBackoffFactor: 2,  // 重试延迟因子
      initialConnectionBackoffDelay: .milliseconds(100),  // 初始重试延迟
      connectionRetryTimeout: .seconds(60)  // 连接重试超时
    )
  )
    // 2. 简单的队列配置
  try app.queues.use(
    .redis(
      .init(
        hostname: "127.0.0.1",
        port: 6379,
        password: "Zhao@19930612",
        pool: .init(
          maximumConnectionCount: .maximumActiveConnections(20),  // 最大活动连接数
          minimumConnectionCount: 5,  // 最小连接数
          connectionBackoffFactor: 2,  // 重试延迟因子
          initialConnectionBackoffDelay: .milliseconds(100),  // 初始重试延迟
          connectionRetryTimeout: .seconds(60)  // 连接重试超时
        )
      )))
  
    // 3. 配置定时任务
  app.queues.schedule(DailyStatisticsJobs()).daily().at(.midnight)
  app.queues.schedule(HourlyStatisticsJobs()).hourly().at(0)
  app.queues.schedule(RankingCacheJobs()).minutely().at(0)
  app.queues
    .schedule(MonthlyStatisticsJobs())
    .monthly()
    .on(.first)
    .at(.midnight)
  app.queues.schedule(AlbumWordCountValidationJob())
    .weekly().on(.monday).at(.noon)
  
    // 注册最近7天音频统计任务，每天凌晨2点执行
  app.queues.schedule(RecentAudiosStatisticsJob()).hourly().at(0)
  app.queues.schedule(TagsDistributionJob()).hourly().at(0)
  
    // 笔记复习相关的任务
  app.queues.schedule(DailyReviewStatsRefreshJob()).daily().at(1, 0)
  
    // 收藏夹数据一致性检查任务，每周一凌晨3点执行
  app.queues.schedule(FavoriteConsistencyJob()).weekly().on(.monday).at(3, 0)
  
  app.queues.schedule(DataConsistencyJob()).weekly().on(.monday).at(.midnight)
    // 4. 启动队列
  try app.queues.startInProcessJobs(on: .default)
  try app.queues.startScheduledJobs()
    // MARK: - 配置迁移
  try await app.autoMigrate()
  app.migrations.add(User.Migration())
  app.migrations.add(Album.Migration())
  app.migrations.add(Audio.Migration())
  app.migrations.add(History.Migration())
  app.migrations.add(History.AddDeleteFieldsToHistoryMigration())
  app.migrations.add(History.AddHistoryIndexes())
  app.migrations.add(History.AddListenStatusToHistoryMigration())
  app.migrations.add(Favorite.Migration())
  app.migrations.add(Transcript.Migration())
  app.migrations.add(Note.Migration())
  app.migrations.add(Tag.Migration())
  app.migrations.add(AlbumTag.Migration())
  app.migrations.add(DailyStatistics.Migration())
  app.migrations.add(Album.AddWordCountField())
  app.migrations.add(ValidationLog.Migration())
  app.migrations.add(Note.AddTimestampAndTagsToNote())
  app.migrations.add(Note.AddLikeInformation())
  app.migrations.add(Feedback.Migration())
  app.migrations.add(NoteTag.Migration())
  app.migrations.add(Note.UpdateContentFieldType())
  app.migrations.add(Note.AddReviewStatus())
  app.migrations.add(NoteReview.Migration())
  app.migrations.add(UserReviewSettings.Migration())
  app.migrations.add(Note.AddAnswerAndArabicFields())
  app.migrations.add(NoteReview.AddAnkiAlgorithmFields())
  app.migrations.add(UserReviewSettings.AddAnkiFieldsMigration())
  app.migrations.add(User.AddCurrentStreakField())
  app.migrations.add(User.AddDailyGoalField())
  app.migrations.add(User.AddPointsSystemFields())
  app.migrations.add(Playlist.Migration())
  app.migrations.add(Folder.Migration())
  app.migrations.add(Favorite.AddFolderFieldMigration())
  app.migrations.add(Folder.AddPositionFieldMigration())
  app.migrations.add(Favorite.AddPositionFieldMigration())
  app.migrations.add(UserSortPreference.Migration())
  app.migrations.add(AddEndTimeToTranscriptMigration())
  app.migrations.add(PointsHistory.Migration())
  app.migrations.add(User.AddTermsFields())
  app.migrations.add(User.AddAppleUserIDField())
  
    // MARK: - 配置中间件
  app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory))
  app.middleware.use(app.sessions.middleware)
  app.middleware.use(ErrorMiddleware.default(environment: app.environment))
  app.middleware.use(CORSMiddleware())
  app.databases.middleware.use(HistoryMiddleware(app: app))
  try await app.autoMigrate()
    // MARK: - 配置压缩
    //  app.middleware.use(CompressionMiddleware())
  
    // MARK: - 配置会话
  app.sessions.use(.redis)
  
    // register routes
  try routes(app)
  
}

  // MARK: - 扩展Application以支持各种服务
extension Application {
    // 腾讯云短信服务
  private struct TencentSMSKey: StorageKey {
    typealias Value = TencentSMSService
  }
  
  var tencentSMS: TencentSMSService {
    get {
      guard let service = storage[TencentSMSKey.self] else {
        fatalError("腾讯云短信服务尚未配置，请在configure中配置")
      }
      return service
    }
    set {
      storage[TencentSMSKey.self] = newValue
    }
  }
  
    // 腾讯云邮件服务
  private struct TencentEmailKey: StorageKey {
    typealias Value = TencentEmailService
  }
  
  var tencentEmail: TencentEmailService {
    get {
      guard let service = storage[TencentEmailKey.self] else {
        fatalError("腾讯云邮件服务尚未配置，请在configure中配置")
      }
      return service
    }
    set {
      storage[TencentEmailKey.self] = newValue
    }
  }
}

  // MARK: - 扩展Request以支持验证码服务
extension Request {
  var verificationCodeService: VerificationCodeService {
    return VerificationCodeService()
  }
}
